package com.lgt_enterprise_android.utils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.model.GlideUrl;
import com.lgt_enterprise_android.BuildConfig;
import com.lgt_enterprise_android.Constant;
import com.lgt_enterprise_android.base.BaseActivity;
import com.lgt_enterprise_android.base.MyApp;
import com.lgt_enterprise_android.view.pages.LoginActivity;
import com.util.AppUtil;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.UUID;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;

/**
 * 作者：minj on 2017/9/27 09:55
 * 网络请求的底层封装
 */
public class BasicHttp {

    public interface IMyCallBack {
        void onResponse(Object resonseObj);

        void onFailure(String mes);
    }

    public static OkHttpClient mOkHttpClient;

    private BasicHttp() {
    }


    static {
        OkHttpClient.Builder builder = getTrustAllClient();

        //让Glide支持https
        Glide.get(MyApp.getInstance()).getRegistry().replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(builder.build()));

        builder.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                String temp = "{'Version':'" + AppUtil.getVersionName(MyApp.getInstance()) + "','Platform':2,'OSVersion':" + android.os.Build.VERSION.SDK_INT + "}";

                Request request = chain.request()
                        .newBuilder()
                        .addHeader("device-info", temp.replace("'", "\""))
                        .build();
                return chain.proceed(request);
            }


        });

        if (BuildConfig.DEBUG) {
            builder.addInterceptor(new LoggingInterceptor());
        }
        mOkHttpClient = builder.build();
    }

    private static SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            MyTrustManager mMyTrustManager = new MyTrustManager();
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{mMyTrustManager}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception ignored) {
            ignored.printStackTrace();
        }

        return ssfFactory;
    }

    //实现X509TrustManager接口
    public static class MyTrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    //实现HostnameVerifier接口
    private static class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    public static OkHttpClient.Builder getTrustAllClient() {
        OkHttpClient.Builder mBuilder = new OkHttpClient.Builder();
        mBuilder.sslSocketFactory(createSSLSocketFactory()).hostnameVerifier(new TrustAllHostnameVerifier());
        return mBuilder;
    }


    public static BasicHttp getInstance(Context context) {
        return null;
    }


    /***
     *
     * @param context
     * @param url
     * @param postData
     * @param myCallBack
     * @return true表示已经发出请求 false表示有可能由于网络问题 请求没有发出去
     */
    public static boolean postExec(final Context context, String url, RequestBody postData, final IMyCallBack myCallBack) {
        if (!AppUtil.isNetworkAvailable(context)) {
            if (context instanceof BaseActivity) {
                ((BaseActivity) context).showToast("网络不给力，请稍后再试");
            }
            return false;
        }

        Request request = new Request.Builder().url(url).addHeader("Authorization", "Bearer " + Constant.token).post(postData).build();


        //new call
        Call call = mOkHttpClient.newCall(request);

        //请求加入调度
        common_exec(context, call, myCallBack);
        return true;
    }

    private static void common_exec(final Context context, Call call, final IMyCallBack myCallBack) {

        //请求加入调度
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {

                if (myCallBack == null) {
                    return;
                }

                if (BuildConfig.DEBUG) {
                    Log.i("HTTP", "onFailure***************************" + e.getLocalizedMessage());
                }

                if (context instanceof BaseActivity) {
                    ((BaseActivity) context).runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            myCallBack.onFailure(e.getMessage());
                        }
                    });
                } else {
                    myCallBack.onFailure(e.getMessage());
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String responseData = response.body().string();

                if (StringUtil.isEmpty(responseData)) {
                    if (context instanceof BaseActivity) {
                        ((BaseActivity) context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                ((BaseActivity) context).showToast("服务错误");
                            }
                        });
                    }
                    return;
                }

                JSONObject tmp = null;

                try {
                    tmp = JSONObject.parseObject(responseData);
                } catch (Exception ex) {

                }

                if (tmp == null) {
                    if (context instanceof BaseActivity) {
                        ((Activity) context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                ((BaseActivity) context).showToast("服务错误，请稍后再试");
                                ((BaseActivity) context).dismissLoadingDialog();
                            }
                        });
                    }
                    return;
                }


                final JSONObject jsonObject = tmp;

                String code = jsonObject.getString("code");

                if ("40003".equals(code) || "40004".equals(code)) {
                    Intent intent = new Intent(context, LoginActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    PrefUtils.setSharedPrefStringData(context, PrefUtils.TOKEN, "");
                    context.startActivity(intent);
                }

                if ("10000".equals(code)) {
                    if (myCallBack == null) {
                        return;
                    }
                    if (context instanceof BaseActivity) {
                        ((Activity) context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                myCallBack.onResponse(jsonObject.get("data"));
                            }
                        });
                    } else {
                        myCallBack.onResponse(responseData);
                    }
                } else {
                    final String msg = jsonObject.getString("message");

                    if (context instanceof BaseActivity) {
                        ((BaseActivity) context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (!StringUtil.isEmpty(msg)) {
                                    Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
                                }
                                if (myCallBack != null) {
                                    myCallBack.onFailure(msg);
                                }
                            }
                        });
                    } else {
                        if (myCallBack != null) {
                            myCallBack.onFailure(msg);
                        }
                    }
                }
            }
        });
    }


    public static boolean getExec(final Context context, String url, final IMyCallBack myCallBack) {

        if (!AppUtil.isNetworkAvailable(context)) {
            if (context instanceof BaseActivity) {
                ((BaseActivity) context).showToast("网络不给力，请稍后再试");
            }
            return false;
        }

        Request request = new Request.Builder().url(url).addHeader("Authorization", "Bearer " + Constant.token).build();
        //new call
        Call call = mOkHttpClient.newCall(request);
        common_exec(context, call, myCallBack);
        return true;
    }


    public static class LoggingInterceptor implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            //这个chain里面包含了request和response，所以你要什么都可以从这里拿
            Request request = chain.request();


            long t1 = System.nanoTime();//请求发起的时间

            RequestBody requestBody = request.body();
            String body = null;
            if (requestBody != null) {
                Buffer buffer = new okio.Buffer();
                requestBody.writeTo(buffer);
                MediaType contentType = requestBody.contentType();
//                    if (contentType != null) {
//                        charset = contentType.charset(UTF8);
//                    }
                body = buffer.readString(Charset.defaultCharset());
            }

            Log.d("HTTP", "**********************************发送请求: method：" + request.method()+"#"+request.url()+  "#" + body);

            Response response = chain.proceed(request);

            long t2 = System.nanoTime();//收到响应的时间

            //这里不能直接使用response.body().string()的方式输出日志
            //因为response.body().string()之后，response中的流会被关闭，程序会报错，我们需要创建出一
            //个新的response给应用层处理
            ResponseBody responseBody = response.peekBody(1024 * 1024);

            LogX.snipet("******HTTP_RESPONSE******", String.format("接收响应: [%s] %n返回json:【%s】 %.1fms%n",
                    response.request().url(),
                    responseBody.string(),
                    (t2 - t1) / 1e6d));

            return response;
        }
    }


    public static void upload(Context context, String url, RequestBody requestBody, IMyCallBack callBack) {

        if (!AppUtil.isNetworkAvailable(context)) {
            if (context instanceof BaseActivity) {
                ((BaseActivity) context).showToast("网络不给力，请稍后再试");
            }
            return;
        }


        Request request = new Request.Builder()
                .header("Authorization", "Client-ID " + UUID.randomUUID())
                .url(url)
                .post(requestBody)
                .build();

//        Response response;

        Call call = mOkHttpClient.newCall(request);

        //请求加入调度
        common_exec(context, call, callBack);

//        try {
//            response= mOkHttpClient.newCall(request).execute();
//            return response.body();
//        }catch (Exception ex){
//            return null;
//        }
    }


}
